import Base from "@/entity/Base";
import TableNameEnum from "@/enumeration/TableNameEnum";
import Optional from "@/utils/Optional";

/**
 * 数据库实例
 */
export default class DbInstance<T extends Base> {

    private readonly name: TableNameEnum;
    private parentId: string = '';

    constructor(name: TableNameEnum) {
        this.name = name;
    }

    setParentId(parentId: string) {
        this.parentId = parentId;
    }

    private buildId(id: string): string {
        if (this.parentId) {
            return `${this.name}-${this.parentId}-${id}`;
        }
        return `${this.name}-${id}`;
    }

    list(): Array<T> {
        return utools.db.allDocs(this.name).map(e => e.value)
    }

    one(id: string): T | null {
        return Optional.ofNullable(utools.db.get(this.buildId(id)))
            .attr('value')
            .orElse(null);
    }

    save(record: T, random: boolean = true): string {
        let id
        if (random) {
            id = new Date().getTime() + '';
        } else {
            id = record.id;
        }
        record.id = id;
        record.createTime = new Date();
        record.updateTime = new Date();
        let re = utools.db.put({
            _id: this.buildId(id),
            value: record
        });
        if (re.error) {
            throw new Error(re.message);
        }
        return id;
    }

    update(record: T): void {
        const id = record.id;
        if (!id || id === '') {
            throw new Error('ID不存在，无法更新');
        }
        let old = utools.db.get(this.buildId(id));
        if (!old) {
            throw new Error('ID失效，无法更新');
        }
        let temp = {} as Base;
        Object.assign(temp, old.value, record);
        temp.updateTime = new Date();
        let re = utools.db.put({
            _id: this.buildId(id),
            _rev: old._rev,
            value: temp
        });
        if (re.error) {
            throw new Error(re.message);
        }
    }

    remove(id: string) {
        utools.db.remove(this.buildId(id));
    }

}